import BpmnModeler from 'bpmn-js/lib/Modeler';
import "bpmn-js/dist/assets/diagram-js.css";
import "bpmn-js/dist/assets/bpmn-font/css/bpmn.css";
import "bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css";
import "bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css";
// 流程模拟
import TokenSimulationModule from 'bpmn-js-token-simulation'
import 'bpmn-js-token-simulation/assets/css/bpmn-js-token-simulation.css'
// 流程图校验部分
import lintModule from 'bpmn-js-bpmnlint'
import bpmnlint from '@/components/properties-panel-extension/modules/Lint/bpmnlint.ts'
import 'bpmn-js-bpmnlint/dist/assets/css/bpmn-js-bpmnlint.css'
// 重写 paletteProvider=》左侧栏
import RewritePalette from '@/components/properties-panel-extension/modules/Palette/index.ts'

// 引入bpmnjs的规则
import CustomRules from "@/components/properties-panel-extension/config/CustomRules.ts"
// 创建和追加任何元素(省略号更多)
import { CreateAppendAnythingModule } from 'bpmn-js-create-append-anything'
// 重写 contextPadProvider
import EnhancementContextPad from '@/components/properties-panel-extension/modules/ContextPad/index'
// 网格背景
import GridLineModule from 'diagram-js-grid-bg'

import { useEffect, useRef, useState } from 'react';
import { initXml } from "./initXml.ts";
import HeaderView from "@/components/properties-panel-extension/components/Header";
// 右侧菜单
import PanelComView from "@/components/properties-panel-extension";
import Definition from './index.module.css'
// 引入对应的JSON
import FlowableModule from "@/components/properties-panel-extension/config/flowable.json"
// 类型引入
import type { Shape, Connection, Label, Root, Parent } from "bpmn-js/lib/model/Types";
// 国际化-目前是汉化
import translate from "@/components/properties-panel-extension/modules/Translate";
import { saveBpmnXml } from "@/api/flowable/definition/BpmHeader";
import { message } from "antd";
import { useLocation } from "react-router-dom";
import { getProcessDefinition } from "@/api/flowable/definition";
import { globalMessage } from '@/utils/message.ts';
import { advancedValidation, BPMN_ELEMENT_LIMITS, checkBpmnElementLimit } from './util/shapeAdd.ts';

// 定义配置选项的类型
interface ModelerOptions {
    [key: string]: any;
}
type BpmnToolsInstance = {
    modeler: any;
    modeling: any;
    moddle: any;
    eventBus: any;
    bpmnFactory: any;
    elementRegistry: any;
    replace: any;
    selection: any;
    canvas: any;
};
const EditorDefinitionView = () => {
    //
    const location = useLocation();

    const [key, setKey] = useState(location.state?.key || '');


    const modelerRef = useRef(null);
    const bpmnModeler = useRef(null);
    // 修改 modeler 配置
    // 初始化模型器配置
    const options: ModelerOptions = {
        minimap: {
            open: false,
            position: {
                x: 20,
                y: 'bottom',
            },
        },
        tokenSimulation: {
            active: false,
        },
        linting: {
            active: false,
            bpmnlint: bpmnlint, // 这里需要提供具体的 bpmnlint 配置或实例
        },
        gridLine: {
            smallGridSpacing: 20,
            gridSpacing: 80,
            gridLineStroke: 0.5,
            gridLineOpacity: 0.6,
            gridLineColor: '#ccc',
        }
    };

    const [bpmnInstance, setBpmnInstance] = useState({});
    // 初始化 bpmn-js 模型器
    const initializeModeler = () => {
        if (!modelerRef.current) return;

        bpmnModeler.current = new BpmnModeler({
            container: modelerRef.current,
            additionalModules: [
                translate,
                EnhancementContextPad,
                GridLineModule,
                TokenSimulationModule,
                lintModule,
                CreateAppendAnythingModule,
                RewritePalette,
                // CustomRules,//导入对应的校验规则
                {
                    __init__: [
                        'FlowableModule',
                        'customRules'
                    ],
                    FlowableModule: ['value', FlowableModule],
                    customRules: ['type', CustomRules]
                },
            ],
            moddleExtensions: {
                flowable: FlowableModule,
            },
            ...options,
        });

        // 注册 bpmn 实例
        const instance = {
            modeler: bpmnModeler.current,
            modeling: bpmnModeler.current.get('modeling'),
            moddle: bpmnModeler.current.get('moddle'),
            eventBus: bpmnModeler.current.get('eventBus'),
            bpmnFactory: bpmnModeler.current.get('bpmnFactory'),
            elementRegistry: bpmnModeler.current.get('elementRegistry'),
            replace: bpmnModeler.current.get('replace'),
            selection: bpmnModeler.current.get('selection'),
            canvas: bpmnModeler.current.get('canvas'),
        };
        setBpmnInstance(instance);
        initModels(instance);
    };

    // 加载流程定义数据
    const loadProcessDefinition = async (key) => {
        try {
            const res: any = await getProcessDefinition(key);
            if (res?.code === 200) {
                await bpmnModeler.current.importXML(res.data);
                console.log('Diagram imported successfully');
            } else {
                console.error('Failed to fetch process definition:', res);
            }
        } catch (err) {
            console.error('Error fetching or importing process definition:', err);
        }
    };
    // 单独的形状添加监听器
    const addShapeAddListener = () => {
        if (!bpmnModeler.current) return;
        bpmnModeler.current.on('shape.add', (e: Shape | Connection | Label | Root | Parent) => {
            console.log("新增元素参数:", e);
            if (!checkBpmnElementLimit(e.parent, e.element)) {

                return handleInvalidAddition(e);
            }
            // 高级规则检查
            const validation = advancedValidation(e.parent, e.element);
            if (!validation.valid) {
                return handleInvalidAddition(e, validation.message);
            }
        });
    };
    // 移除对应的流程
    const handleInvalidAddition = (e: any, customMessage?: string) => {
        const elementType = e.element.type;
        const defaultMessage = `不允许添加更多 ${elementType}`;
        const eventBus = bpmnModeler.current.get('eventBus');
        // 获取建模模块
        // commandStack.postExecuted 表示 上一个命令（如添加元素）已完全执行完毕
        eventBus.once('commandStack.postExecuted', () => {
            const modeling = bpmnModeler.current.get('modeling');
            modeling.removeElements([e.element]);
            globalMessage().warning(customMessage || defaultMessage);
        });
    }
    // 加载默认的初始 XML 数据
    const loadDefaultDiagram = async () => {
        try {
            await bpmnModeler.current.importXML(initXml);
            // 初始化之后再添加新的函数事件
            addShapeAddListener();
            console.log('Default diagram imported successfully');
        } catch (err) {
            console.error('Error importing default diagram:', err);
        }
    };



    useEffect(() => {
        initializeModeler();
        if (key) {
            loadProcessDefinition(key).then(r => console.log(r));
        } else {
            loadDefaultDiagram().then(r => console.log(r));
        }
        return () => {
            if (bpmnModeler.current) {
                bpmnModeler.current.destroy();
            }
        };

    }, [key]);


    // 初始化流程设计器
    const initModels = (instance: BpmnToolsInstance) => {
        getActiveElement(instance);
    }
    const getActiveElement = (instance: any) => {
        // 选中元素变化时，返回新选中的元素对象
        instance.modeler.on('selection.changed', (e: Shape | Connection | Label | Root | Parent) => {
            const newSelection = e.newSelection[0] || null
            initFormOnChanged(newSelection, instance)
        })
        // 元素发生改变时触发，返回发生改变的元素
        instance.modeler.on('element.changed', (e: Shape | Connection | Label | Root | Parent) => {
            initFormOnChanged(e.element || null, instance)
        })
    }
    // 初始化数据
    const initFormOnChanged = (activatedElement: Shape | Connection | Label | Root | Parent, instance: any) => {
        if (activatedElement) {
            setBpmnInstance({ bpmnElement: activatedElement, ...instance })
        } else {
            const canvas = instance.modeler.get('canvas');
            const rootElement = canvas.getRootElement();
            setBpmnInstance({ bpmnElement: rootElement, ...instance })
        }
    }

    const saveXml = (e) => {
        saveBpmnXml({ name: "张三", category: "2", xml: e }).then(() => globalMessage().success("操作成功"));
    }
    return (
        <>
            <div className={Definition.PageClass}>
                <div className={Definition.HeaderClass}>
                    <HeaderView bpmnInstance={bpmnInstance} SaveXMl={saveXml} />
                </div>
                <div
                    ref={modelerRef}
                    style={{
                        width: '100%',
                        height: '100%',
                        position: "absolute",
                        backgroundColor: '#ffffff',
                    }}
                />
                {/*右侧菜单栏*/}
                <div className={Definition.RightPanelClass}>
                    <PanelComView bpmnInstance={bpmnInstance} />
                </div>
            </div>
        </>);
};

export default EditorDefinitionView;
